#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include "wavapi.h"
#include <mmsystem.h>
//#pragma comment(lib, "winmm.lib")
DWORD CALLBACK waveOutProc(HWAVEOUT hwo,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2);
//每次播放缓存大小
#define PLAYBUFFERLENGTH 16384
//设置缓存条
#define WAVEHDR_NUM 2
void PlayWavBySystem(const char*filename){
//sndPlaySound播放文件,其它参考PlaySound
//SND_SYNC同步播放，SND_ASYNC异步播放
	 printf("从文件播放声音!\n");
	 sndPlaySound(filename,SND_SYNC);
}
int PlayWavByWin(const char*filename){
	WavBuffer wavbuff={0};
	WAVEFORMATEX waveFormatEx={0};
	FILE_WAV    fileinfo;
	HWAVEOUT    hWaveOut=NULL;
	WAVEHDR hdr[WAVEHDR_NUM]={0};
	int i=0;
	if(OpenWavFile(filename,&fileinfo,1)==0){
		wavbuff.wav_buffer=(char*)malloc(fileinfo.total);
		wavbuff.wav_length=fileinfo.total;
		ReadWavFile(&fileinfo,wavbuff.wav_buffer,fileinfo.total);
		CloseWavFile(&fileinfo);
		printf("读取成功!\n");
	}else{
		printf("读取失败!\n");
		return -1;
	}
	printf("默认方法播放声音!\n");
	memcpy(&waveFormatEx,&fileinfo.format,sizeof(WAVE_FORMAT));
	printf("音频输出设备数量:%u\n",waveOutGetNumDevs());
	if(waveOutOpen(&hWaveOut,0,&waveFormatEx,(DWORD)(waveOutProc),0,CALLBACK_FUNCTION)!=0){
		printf("打开音频设备错误\n");
		goto exit;
	}
	wavbuff.wav_pos=wavbuff.wav_buffer;
	wavbuff.wav_lastlength=wavbuff.wav_length;
//准备音频缓冲区
	for(i=0;i<WAVEHDR_NUM;i++){
		hdr[i].dwBufferLength=PLAYBUFFERLENGTH;
		hdr[i].lpData=wavbuff.wav_pos;
		hdr[i].dwUser=(DWORD_PTR)&wavbuff;
		wavbuff.wav_pos+=PLAYBUFFERLENGTH;
		wavbuff.wav_lastlength-=PLAYBUFFERLENGTH;
		waveOutPrepareHeader(hWaveOut,&hdr[i],sizeof(WAVEHDR));
	}
//写数据
	for(i=0;i<WAVEHDR_NUM;i++){
		waveOutWrite(hWaveOut,&hdr[i],sizeof(WAVEHDR));
	}
	while(wavbuff.wav_lastlength>0){
	  Sleep(100);
	}
	printf("播放结束\n");
	waveOutPause(hWaveOut);
	Sleep(100);
//释放区间
	for(i=0;i<WAVEHDR_NUM;i++){
		waveOutUnprepareHeader(hWaveOut,&hdr[i],sizeof(WAVEHDR));
	}
	waveOutClose(hWaveOut);
exit:
	free(wavbuff.wav_buffer);
	return 0;
}
DWORD CALLBACK waveOutProc(HWAVEOUT hwo,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2){
	WAVEHDR*pHDR=(WAVEHDR*)dwParam1;
	switch (uMsg){
		case WOM_OPEN:
			printf("WOM_OPEN\n");
			break;
		case WOM_CLOSE:
			printf("WOM_CLOSE\n");
			break;
		case WOM_DONE:{
				WavBuffer*pwavbuff=NULL;
				int templength=0;						
				pwavbuff=(WavBuffer*)pHDR->dwUser;
				templength=pwavbuff->wav_lastlength<PLAYBUFFERLENGTH?pwavbuff->wav_lastlength:PLAYBUFFERLENGTH;
				pHDR->lpData=pwavbuff->wav_pos;
				pHDR->dwBufferLength=templength;
				pwavbuff->wav_pos+=templength;
				pwavbuff->wav_lastlength-=templength;
				//printf("WOM_DONE lastlength:%u\n",pwavbuff->wav_lastlength);	
				waveOutWrite(hwo,pHDR,sizeof(WAVEHDR));
			}
			break;
		default:
			printf("%x\n",uMsg);
	}
	return 0;
}